/**
 * 插件类:代码为源码,使用版本问commonUtil.min.js
 * @author RayChiu
 * @returns
 */
var ComUtil = new CommonPluginsUtil();
function CommonPluginsUtil() {
	
	var that = this;
	
	/**
	 * 智能提示默认在用类标识
	 */
	that.bomcAutoChoosingTag = function () {
		return "bomcAutoChoosingTag";
	}
	
	/**
     * 将对象转成Boolean常量
     */
    that.bool = function(val){
	   return (/^true$/i).test(val); 
    };
    
    that.isNumber = function(val) {
        var reg = /^[\d|\.|,]+$/;
        return reg.test(val);
    };
    
    that.isInt = function(val) {
        if (val === "") {
            return false;
        }
        var reg = /\D+/;
        return !reg.test(val);
    };
    
    that.isEmail = function(email) {
        var reg = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        return reg.test(email);
    };
    
    that.isMobile = function(mobile) {
        var reg = /1[34578]{1}\d{9}$/;
        return reg.test(mobile);
    };
    
    that.isTel = function(tel) {
        var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/; //只允许使用数字-空格等
        return reg.test(tel);
    };
    
    /**
     * 是否是JSON
     */
    that.isJson = function(obj) {
    	return obj && typeof(obj) == "object" && Object.prototype.toString.call(obj).toLowerCase() == "[object object]";
    };
    
	/**
	 * 判断是否数组
	 */
	that.isArray = function (o) {
		return Object.prototype.toString.call(o) === '[object Array]';
	};
	
    /**
     * 判断字符串是否以str开头
     */
    that.isStartWith = function(source,str){
    	return new RegExp("^"+str).test(source); 
    }
	
    /**
     * 判断字符串是否以str结束
     */
    that.isEndWith = function(source,str){
		  return new RegExp(str+"$").test(source);
    }
    
    /**
     * 数据是否为空
     */
    that.isEmpty = function(data) {
        if ($) {
            var data2 = $.trim(data);
        }
        if (ComUtil.isArray(data) && data.length == 0) {
            return true;
        } else if (ComUtil.isJson(data) && isEmptyObject(data)) {
            return true;
        } else if (!data2 && data2 !== 0) {
            return true;
        } else {
            return false;
        }
        // Json是否空对象
        function isEmptyObject(obj) {
            for (var n in obj) {
                return false
            }
            return true;
        }
    };
    
    /** 
     * 时间、日期对象的格式化 
     * date：毫秒时间
     * format：时间格式"yyyy-MM-dd hh:mm:ss"，年-月-日 时：分：秒
     **/
    that.dateFormat = function(date, format) {
        //eg:format="yyyy-MM-dd hh:mm:ss";
        format = format || "yyyy-MM-dd hh:mm:ss";
        date = new Date(Number(date));
        var o = {
            "M+": date.getMonth() + 1, // month
            "d+": date.getDate(), // day
            "h+": date.getHours(), // hour
            "m+": date.getMinutes(), // minute
            "s+": date.getSeconds(), // second
            "q+": Math.floor((date.getMonth() + 3) / 3), // quarter
            "S": date.getMilliseconds()
        };
        if (/(y+)/.test(format)) {
            format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        }
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
            }
        }
        return format;
    };

    /** 
     * 日期追加时间
     * time：时间（yyyy/MM/dd,yyyy/MM/dd hh:mm:ss,yyyy-MM-dd hh:mm:ss）
     * days：追加天数
     * format：返回时间格式
     * @author kebai
     * @date 2016-8-10
     **/
    that.dateAddTime = function(time, days, format) {
        if (time.indexOf('-') != -1) {
            time = time.replace(/\-/g, '/');
        }
        var newTime = new Date(time).getTime() + days * 24 * 60 * 60 * 1000;

        newTime = ComUtil.dateFormat(newTime, format);

        return newTime;
    };
    
    /** 
     * 当前时间是星期几
     * @time date
     * @return
     * 1,2,3,4,5,6,7
     **/
    that.dateDay = function(date) {
    	if (!date) {
    		date = new Date();
    	}
    	if (!ComUtil.isEmpty(date)){
    		date = new Date(Number(date));
    	}
    	return date.getDay() == 0 ? "7" : date.getDay();
    };
    
    /** 
     * 获取上个月的开始日期和结束日期
     * @return
     * [上个月第一天，上个月最后一天]
     **/
    that.dateOfLastMonth = function() {
    	var arr = new Array(),
    		nowdays = new Date(),
    		year = nowdays.getFullYear(),
    		month = nowdays.getMonth();
        if(month == 0) {
            month = 12;
            year = year - 1;
        }
        if (month < 10) {
            month = "0" + month;
        }
        //上个月的第一天
        arr[0] =  year + "-" + month + "-" + "01 00:00:00";
        //上个月的最后一天
        var endDate = new Date(year, month, 0);
        arr[1] = year + "-" + month + "-" + endDate.getDate() + " 23:59:59";
        return arr;
    };
    
    /**
     * 关闭父页面中弹出的子窗口并刷新父页面数据
     * @param callBack
     * 父页面的方法
     * @param params
     * 传给父页面的参数,参数形式自定义
     */
    that.closeParentLayer = function(callBack, params) {
		parent.layer.close(parent.layer.getFrameIndex(window.name));
		if (callBack && typeof callBack === "function") {
			callBack(params ? params : '');
		} else {
			parent.window.location.reload();
		}
    }
    
    /**
	 * 弹出层
	 * @param title
	 * 弹出层窗口标题
	 * @param url
	 * 弹出层页面地址
	 * @param area
	 * 窗口宽度
	 */
    that.openWin = function(title, url, area){
		var defaultarea = ['600px', '400px']
		if (area) {
			defaultarea = area;
		}
		return ComUtil.openLayerWin(title, url,{
			area : defaultarea
		}, false);
	}
    
	/**
	 * 弹出层
	 * @param title
	 * 弹出层窗口标题
	 * @param url
	 * 弹出层页面地址
	 * @param options
	 * 配置项
	 * @param useLayerBtn
	 * 是否适用默认的layer的弹出层按钮
	 */
	that.openLayerWin = function(title, url, options, useLayerBtn) {
		var win = window.top === window.self ? window : parent.window;
		var layer_width = $(win).width()-200;
		var layer_height = $(win).height()-130;
		useLayerBtn = useLayerBtn === true ? true : false;
		options = $.extend({}, {
			type: 2,
			title: title,
			content: (url ? url : ""),
			shadeClose: true, 
			maxmin: true, 
			maxmin:true,
			shade: 0.5,
			scrollbar: false,										// 是否允许浏览器出现滚动条,默认屏蔽
			fixed: true, 											// 默认固定
			area: [layer_width+'px', layer_height+'px'],								// 默认大小,[宽,高]
			btn: (useLayerBtn ? ['确定', '取消'] : null),				// 按钮
			btnAlign: 'c',											// 默认按钮居中
			success: null,											// 层弹出后的成功回调方法
			yes: null,												// 层弹出后的确认按钮回调方法
			cancel: null,											// 层弹出后的右上角关闭按钮方法
			full: function(elem) {
				var win = window.top === window.self ? window : parent.window;
				$(win).on('resize', function() {
					var $this = $(this);
					elem.width($this.width()).height($this.height()).css({
						top: 0,
						left: 0
					});
					elem.children('div.layui-layer-content').height($this.height() - 95);
				});
			}
		}, options);
		return layer.open(options);
	}

	/**
	 * 通用Layer Open弹出层控件,能设置父子页面交互参数和回调方法等
	 * 
	 * @param objId
	 * 受益对象,形如 #inputId,不要丢失#号
	 * @param childOptions
	 * 父子页面交互配置项
	 * @param layerOptions
	 * 弹出层配置项
	 */
	that.plusLayerOpen = function (objId, childOptions, layerOptions) {
		// TODO 
		$(objId).data('data',$.extend({},childOptions));
		layerOptions = $.extend({}, {
			title: "选择窗口",							// 窗口名称
			id: "alayerForm_" + new Date().getTime(),	// 随机一个窗口ID
			pageUrl: '',								// 窗口子页面地址参数子页面自取去objId取data
			useLayerBtn: true,							// 是否适用默认的Layer弹出层按钮,false时请在childOptions设置子页面中要调用的父页面方法chdParentCallMethd,此方法固定返回选择的数据的JSON数组
			yes: function(index, layero) {
	            var iframeWin = ComUtil.getLayerOpenIframWin(index, layero, layerOptions.id);
	          	// TODO 执行用户自定义的回调确认函数
	          	try {
	          		if (layerOptions.callUserYes && typeof layerOptions.callUserYes === "function") {
		          		layerOptions.callUserYes(index, layero, iframeWin);
		          	}
				} catch (e) {}
				// 需要手动关闭窗口
	            layer.close(index);
			},
			btn2: function(index, layero) {		// 按钮二事件 
				
			},
			cancel: function(index, layero) {	// 右上角关闭事件 
				
			}
		},layerOptions);
		return ComUtil.openLayerWin(layerOptions.title, layerOptions.pageUrl, layerOptions, layerOptions.useLayerBtn);
	}
	
	/**
	 * 加载弹出层树型选择确认控件
	 * 
	 * @tips 需要引入layer.js、JQuery、Ztree等相关资源
	 * 
	 * @param objId
	 * 受益对象,形如 #inputId,不要丢失#号
	 * @param childOptions
	 * 父子页面交互配置项,具体参考/common/plugins/tree-choose.jsp的tree-choose.js或者本方法中的childOptions
	 * @param layerOptions
	 * 弹出层配置项
	 * @return
	 * 返回值会自动根据$(objId)自动设置,如果需要设置隐藏值dataSetIdable=true,则隐藏值会自动设置到$(objId)后面紧接着的隐藏input里
	 */
	that.plusTreeChoose = function (objId, childOptions, layerOptions) {
		// 父子页面交互配置项
		childOptions = $.extend({}, {
			cfgUsingClass: 
				ComUtil.bomcAutoChoosingTag(),			// 默认在用类标识
			mutiable: false,							// 子页面树加载后是否多选,默认单选
			multipleSeparator: ",",						// 多选时值的分隔符号,默认","号
			onlyLeaf: false, 							// 是否仅选择叶子节点,默认[false]
			helpSearch : false, 						// 是否显示辅助搜索框,默认不显示[false]
			helpSearchPMKey : "q",						// 定义输入查询关键字对应参数名称
			helpSearchShowRg: false,					// 是否显示辅助搜索框搜索右边展示value,默认不显示[false]
			rightListShow: false,						// 显示右侧已选栏,默认不显示
			idKey: 'id',								// Ztree节点idKey,默认[id]
			pIdKey: 'pId',								// Ztree节点pIdKey,默认[pId]
			zName: 'name',								// Ztree节点名称name,默认[name]
			trueParent : false, 						// 树节点中是否含trueParent字段
			chdUrlOrData: null,							// 子页面树加载地址或惊涛数据,请尽量使用URL
			chdParams: null,							// 子页面树加载地址请求默认参数JSON,也可以是传递给子页面的参数(包含已选值,需要用户自己设定)
			dataSetIdable : true,						// 选择后是否需要设置隐藏ID值
			dataColumnId : childOptions.idKey||'id',	// 选择后隐藏的字段,默认[id]
			dataColumnName : "name",					// 选择后返回给父页面显示的字段,默认[name]
			dataShowName : "name",						// 选择后显示在右边已选框中的字段,默认[name]
			dataColumns: null,							// 选择后返回给父页面的额外字段数组,默认返回dataColumnId,dataColumnName
			chdChiooseObjId: objId,						// 父页面中的选择受益对象元素(必须设置),用于子页面获取已选值的显示名称,同时用于默认方法设置弹出层返回的选择值
			chdChiooseHideObjId: null,					// 父页面中的选择受益异常对象,null默认受益对象后面的隐藏对象元素,当chdChiooseObjId相邻下一个隐藏INPUT元素找不到时不设置隐藏值,同时用于子页面获取已选值的隐藏ID值
			chdParentCallMethd: null					// 父页面中让子页面确定按钮的回调方法[此方法必须是父页面全局函数],仅在useLayerBtn=false【不使用layer UI默认的弹窗按钮时（即使用子页面自定义的按钮时的回调方法）】有效
		}, childOptions);
		
		// 再次设置传递的已选值
		childOptions.chdParams = (function(){
			return $.extend({},{
				ids : (function() {// 参数KEY固定为ids,必须和dataColumnId字段相对应
					var $hidenObj = getHideObj();
					if ($hidenObj) {
						return $hidenObj.val()
					}
					return null;
				})(),
				names : (function() {// 参数KEY固定为names,必须和dataColumnName字段相对应
					return $(childOptions.chdChiooseObjId).val();
				})()
			},childOptions.chdParams)
		})();
		
		// TODO 优先加载标识,不能放倒success回调方法里面
		addDataParamsTag(childOptions);
		// 弹出层配置项
		layerOptions = $.extend({},{
			title: "选择窗口",							// 窗口名称
			pageUrl: viewsPath + "common/chosen/tree-choose.jsp",	// 窗口子页面地址,窗口子页面参数请使用childOptions.chdParams传递
			id: "alayerForm_" + new Date().getTime(),	// 随机一个窗口ID
			useLayerBtn: true,							// 是否适用默认的Layer弹出层按钮,false时请在childOptions设置子页面中要调用的父页面方法chdParentCallMethd,此方法固定返回选择的数据的JSON数组
			shadeClose: true,							// 允许点击shade关闭弹出层 就设置成true
			callDefaultYes: true,						// 点击确认后是否执行默认的回调函数,默认参数index, layero, results(返回值)
			callUserYes: null,							// 用户自定义的确认回调函数
			area: (function(){
				if (childOptions.rightListShow) {
					return ['800px','590px'];			// 展示右边已选栏时的宽度和高度
				} else {
					return ['400px','590px'];			// 不展示右边已选栏时的宽度和高度
				}
			})(),					// 弹出层的宽高
			rightListShow: false,						// 弹出层页面是否显示右侧已选栏
			success: function(index, layero) {			// 成功打开弹出层后的回调函数
				
			},
			yes: function(index, layero) {
	            var iframeWin = ComUtil.getLayerOpenIframWin(index, layero, layerOptions.id);
	            var cdatas = iframeWin.layerWinBack();
	            // 当允许调用默认的YES回调函数时执行
	          	if (layerOptions.callDefaultYes && cdatas && ComUtil.isArray(cdatas)) {
	          		var CNames = [],
	          			CIds = [],
	          			$objId = $(childOptions.chdChiooseObjId), 
	          			$hidenObj = getHideObj();
	          		
	          		for (var i = 0,l = cdatas.length; i < l; i++) {
						CIds.push(cdatas[i][childOptions.dataColumnId]);
						CNames.push(cdatas[i][childOptions.dataColumnName]);
					}
	          		
	          		$objId.val(CNames.join(childOptions.multipleSeparator) 
	          				+ ((CNames.length > 0) ? (childOptions.mutiable ? childOptions.multipleSeparator : "") : ""));
	          		if (childOptions.dataSetIdable && $hidenObj) {
	          			$hidenObj.val(CIds.join(childOptions.multipleSeparator));
	          		}
	          	}
	          	// TODO 执行用户自定义的回调确认函数
	          	try {
	          		if (layerOptions.callUserYes && typeof layerOptions.callUserYes === "function") {
		          		layerOptions.callUserYes(index, layero, cdatas);
		          	}
				} catch (e) {}
	          	// 移除标志
				removeDataParamsTag();
				// 需要手动关闭窗口
	            layer.close(index);	
			},
			btn2: function(index, layero) {		// 按钮二事件 
				removeDataParamsTag();
			},
			cancel: function(index, layero) {	// 右上角关闭事件 
				removeDataParamsTag();
			}
		}, layerOptions);
		
		// TODO 添加引用参数和using Tag
		function addDataParamsTag() {
			// 一个Dom树中最多仅允许一个元素正在使用该控件
			$("." + childOptions.cfgUsingClass).removeClass(childOptions.cfgUsingClass);
			$(objId).addClass(childOptions.cfgUsingClass);
//			$(objId).attr("data-options", JSON.stringify(childOptions));
			$(objId).data("data-options", childOptions);
		}
		
		// TODO 取消参数设置
		function removeDataParamsTag() {
			$(objId).removeClass(childOptions.cfgUsingClass);
//			$(objId).attr("data-options","");
			$(objId).data("data-options", {});
		}
		
		// TODO 仅适用于此控件的获取隐藏ID值元素对象的方法
		function getHideObj() {
			if (childOptions.dataSetIdable) {
				var $objId = $(childOptions.chdChiooseObjId)
	 			var $hidobj = $objId.next("input[type=hidden]");
				if (childOptions.chdChiooseHideObjId) {
					$hidobj = $(childOptions.chdChiooseHideObjId);
				}
				return $hidobj;
	 		}
			return null;
		}
		
		return ComUtil.openLayerWin(layerOptions.title, layerOptions.pageUrl, layerOptions, layerOptions.useLayerBtn);
	}
	
	/**
	 * 获取layer.open中用type=2方式打开的弹出层的layer默认按钮回调函数中获取窗口子页面对象的方法
	 * @param index
	 * 回调函数的固定参数
	 * @param layero
	 * 回调函数的固定参数
	 * @param layerWindowId
	 * layer.open({配置项})中的配置型给的弹出层的ID
	 */
	that.getLayerOpenIframWin = function(index,layero,layerWindowId) {
		if (!index || !layero) {
			return null;
		}
//		var body = layer.getChildFrame('body', index);
        var iframeWin = window[layero.find('iframe')[0]['name']];
        if (!iframeWin) {
        	 var frameId = document.getElementById(layerWindowId).getElementsByTagName("iframe")[0].id;
        	 iframeWin = $('#'+frameId)[0].contentWindow;
        }
       return iframeWin;
	}
	
	/** 
     * Ajax请求数据,默认同步请求
     * obj：对象
     * url：接口路径
     * callBack：接口请求回调函数
     * paramDataJson：传参数据
     * @options - default:
     * 		type:请求方式类型，默认get方式请求 
     * 		async：请求类型，默认异步请求      
     * 		dataType：返回数据类型，默认为json 
     **/
	that.AjaxData = function(obj, url, callBack, paramDataJson, options) {
		options = $.extend({},{
			async: false
		}, options);
		this.AjaxPost.call(that, obj, url, callBack, paramDataJson, options);
	}
	
	/** 
     * Ajax请求提交,默认异步请求
     * obj：对象
     * url：接口路径
     * callBack：接口请求回调函数
     * paramDataJson：传参数据
     * @options - default:
     * 		type:请求方式类型，默认get方式请求 
     * 		async：请求类型，默认异步请求      
     * 		dataType：返回数据类型，默认为json 
     **/
	that.AjaxPost = function(obj, url, callBack, paramDataJson, options) {
		if (!url) {
			return;
		}
		options = $.extend({},{
			debug: false,		// 是否调试处理
			cfgIsList: false,
			cfgLoading: false 	// 是否显示遮罩层
		},options);
		// TODO 提交批量数据还是普通数据
		var isList = options.cfgIsList === true ? true : false;
		if (!isList) { 				//普通提交
			paramDataJson = paramDataJson || '';
			options = $.extend({},{
				data: paramDataJson,
			},options);
		} else { 					//提交List数组
			paramDataJson = paramDataJson || [];
			options = $.extend({},{
				type: 'POST',		// 默认POST
				data: JSON.stringify(paramDataJson),
				contentType: 'application/json',//这样就可以将一个或者多个对象数组传到Spring mvc controller端，使用@RequestBody即可绑定对象或者List.
			},options);
		}
		// TODO 提交批量数据还是普通数据
		options = $.extend({}, {
			url: url,			// 设置请求地址
			type: 'POST',		// 默认POST
			async: true,		// 请求类型，默认同步请求
			dataType: 'json',	// 返回数据类型，默认为json
			success: function(result) {
				loadding(false);
				if (typeof callBack === "function") {
					callBack(obj, result, paramDataJson);
				} else {// 采用默认处理
					if (result.stutas == "success") {
  						layer.msg('操作成功!', {icon: 1});
	  				} else {
	  					layer.msg('操作异常!', {icon: 2});
	  				}
				}
            },
            error: function(e,e1,e2) {
            	layer.msg('服务繁忙或者网络已断开,请稍候再试!', {icon: 2, time: 1000});
            	loadding(false);
            	return;
            }
		},options);
		// 调试处理
		if (options.debug) {
			console.log('Ajax options:', options);
			return;
		}
		try {
			loadding(true);
			$.ajax(options);
		} catch (e) {
			loadding(false);
			throw e;
		}
		
		function loadding(on) {
			on = on === true ? true : false;
			if (on && options.cfgLoading) {
				options.layIndex = ComUtil.loading();
			}
			if (!on && options.cfgLoading) {
				ComUtil.closeLoading(options.layIndex);
			}
		}
	}
	
	/**
	 * 加载遮罩层
	 */
	that.loading = function(options) {
		return layer.load(2,$.extend({},{time: 10*1000,shade: [0.6,'#fff'],shadeClose : true},options));
	}
	
	/**
	 * 关闭遮罩层
	 * @param layIndex
	 */
	that.closeLoading = function(layIndex) {
		if (layIndex) {
			layer.close(layIndex);
		} else {
			layer.closeAll('loading');
		}
	}
	
	/**
	 * Ajax请求删除固定方法
	 */
	that.AjaxFnDelete = function(url, callBack, paramDataJson, options) {
		options = $.extend({},{
			msg: '确认删除?'
		},options);
		layer.confirm(options.msg, {
			btn: ['确认','取消'] //按钮
		}, function() {
			delete options.msg;
			ComUtil.AjaxPost('body', url, callBack, paramDataJson, $.extend({}, {
				type: 'POST',
				cfgLoading: true
			}, options));
			layer.closeAll('dialog');
		}, function() {
			if (options && options.cfgFnCancel && typeof options.cfgFnCancel === "function") {
				options.cfgFnCancel();
			} else {
				// layer.msg('已取消', {icon: 2});
			}
		});
	}
	
	/**
	 * prompt方法
	 */
	that.AjaxFnPrompt = function(title, callBack) {
		var options = $.extend({},{
			title: title
		},options);
		layer.prompt(options, function(text, index) {
			callBack(text)
			layer.close(index);
		});
	}
	
	/**
	 * Ajax确认框
	 */
	that.AjaxFnConfirm = function(url,callBack, paramDataJson, options) {
		options = $.extend({},{
			msg: '确认操作?'
		},options);
		layer.confirm(options.msg, {
			btn: ['确认','取消'] //按钮
		}, function() {
			delete options.msg;
			ComUtil.AjaxPost('body', url, callBack, paramDataJson, $.extend({}, {
				type: 'POST',
				cfgLoading: true
			}, options));
			layer.closeAll('dialog');
		}, function() {
			if (options && options.cfgFnCancel && typeof options.cfgFnCancel === "function") {
				options.cfgFnCancel();
			} else {
				// layer.msg('已取消', {icon: 2});
			}
		});
	}
	
	/** 
     * 获取指定div中所有表单字段，包括隐藏input，json形式返回
     * obj：div或者form对象
     * flag:值是否要encodeURI编码，默认false不编码，(表单post请求不要编码，get请求则需要编码)
     * valStrType:值为字符串类型,数组值转成字符串，默认true(转成字符串,若获取所有表单数据后整体要转成字符串，则这里须设置为false)
     * comma:默认逗号分隔
     * @author kebai
     * @date 2015-7-6
     **/
    that.formJson = function(obj, flag, valStrType, comma) {
        var FormObj = $(obj);
        if (FormObj.length == 0) {
            return;
        }
        flag = flag || false;
        valStrType = valStrType === false ? false : true;
        comma = comma || ',';
        var json = {},
            $this, name, value, valueArr;
        //文本、文本域,非按钮类型
        FormObj.find("input:not('input[type=radio],input[type=checkbox],input[type=bottom],input[type=submit]'),textarea").each(function() {
            $this = $(this);
            name = $this.attr('name');
            value = $this.val();
            if (!value && value != 0) {
                value = ''
            };
            if (value == $this.attr('placeholder')) {
                value = ''
            }
            if (flag && value) {
                value = encodeURI(value);
            }
            if (name) {
                json[name] = value
            }
        });
        //下拉
        FormObj.find("select").each(function() {
            $this = $(this);
            name = $this.attr('name');
            value = $this.val();
            if (!value && value != 0) {
                value = ''
            };
            if (ComUtil.isArray(value)) {
                //多选
                if (valStrType) {
                    value = ComUtil.toJson(value, false);
                }
                if (name) {
                    json[name] = value;
                }
            } else {
                //单选
                if (flag && value) {
                    value = encodeURI(value);
                }
                if (name) {
                    json[name] = value
                }
            }
        });
        //单选框
        FormObj.find("input[type=radio]").each(function() {
            $this = $(this);
            name = $this.attr('name');
            value = $this.val();
            if (!value && value != 0) {
                value = ''
            };
            if (flag && value) {
                value = encodeURI(value);
            }
            if (name && $this.is(':checked')) {
                json[name] = value;
            }
        });
        //复选框
        var checkName, checkArr = [];
        FormObj.find("input[type=checkbox]").each(function() {
            $this = $(this);
            checkName = $this.attr('name');
            if (!json[checkName]) {
                checkArr = [];
            }
            if (checkName && $this.is(':checked')) {
                checkArr.push($this.val());
                valueArr = checkArr;
                if (valStrType) {
                    valueArr = checkArr.join(comma);
                }
                if (flag && valueArr) {
                    valueArr = encodeURI(valueArr);
                }
                json[checkName] = valueArr;
            };
        });
        return json;
    };
    
    /**
     * 将JSON对象转换成传统的URL参数形式
     * @param jsonObject
     * @key 字段的前缀，key为空，换后的参数名默认为json中的字段名称；不为空，转换后的参数名为key.json中的字段名
     * //调用：
     * var obj={name:'tom','class':{className:'class1'},classMates:[{name:'lily'}]};
     * parseParam(obj);
     * 结果："name=tom&class.className=class1&classMates[0].name=lily"
     * parseParam(obj,'stu');
     * 结果："stu.name=tom&stu.class.className=class1&stu.classMates[0].name=lily"
     */
    that.parseParam = function(param, key){
        var paramStr="";
        if (param instanceof String||param instanceof Number||param instanceof Boolean) {
            paramStr+="&"+key+"="+encodeURIComponent(param);
        } else {
            $.each(param,function(i){	
                var k=key==null?i:key+(param instanceof Array?"["+i+"]":"."+i);
                paramStr+='&'+ComUtil.parseParam(this, k);
            });
        }
        return paramStr.substr(1);
    }
    
    /**
     * zTree插件：获取树对象
     */
    that.zTree = function(treeId){
    	return $.fn.zTree.getZTreeObj(treeId);
    }
    
    /**
     * zTree插件：加载Ztree树
     * @param options
     * 		配置项,具体参见方法体内说明
     * options.urlOrData --> 数据源地址或者数据源JsonArray
     * options.mutiable --> 是否仅选择叶子节点,默认[true]
     * options.showTitle --> 是否显示标题,默认不显示[false]
     * @return
     * ZTree树对象:提供操作zTree的各种方法,对于通过js操作zTree来说必须通过此对象
     */
    that.zTreeInit = function(treeId, options){
    	if (!treeId) {
			return;
		}
    	/*************************配置项:开始***********************/
    	var zNodes,
    		isUrl = typeof (options.urlOrData) === "string";
    	options = $.extend({},{
			mutiable: false, 					// 是否多选,默认单选[false]
			onlyLeaf: false, 					// 是否仅选择叶子节点,默认[false]
			checkedParentWhenNoLeaf: false, 	// 当onlyLeaf=true时没有叶子节点是否也选中父节点,默认不选中[false]
			showNodeICon: true, 				// 是否展示节点图标,默认展示
			trueParent: false, 					// 树节点中是否含trueParent字段
			showTitle: false, 					// 是否显示标题,默认不显示[false]
			titleCol: "name", 					// 树节点显示title字段,默认[name],且需设置showTitle=true
			ajxaType: "POST", 					// 远程获取数据的请求方式,默认POST
			clickMask: false, 					// 树节点点击事件是否触发遮罩层
			beforeClick: null, 					// 用户自定义选择前事件,默认null,用户自定义时onlyLeaf无作用,选择前的验证由用户自行定义
			onClick: null, 						// 用户自定义选择事件,默认null
			onCheck: null 						// 用户自定义选择事件,默认null
		}, options);
    	if (isUrl) {
			ComUtil.AjaxData(treeId, options.urlOrData, function(obj, data){
				zNodes = data.data;
			},(options.params || null),{
				type: options.ajxaType,
			});
		} else {
			zNodes = options.urlOrData;
		}
    	/*************************配置项:结束***********************/
    	var ztreeSetting = {
			check : {
				enable : options.mutiable,
				chkboxType : {
					"Y" : "s",
					"N" : "ps"
				},
				half: true
			},
			view : {
				nameIsHTML : true,
				showTitle : options.showTitle,
				showIcon: options.showNodeICon
			},
			data : {
				key: {
    				title: options.showTitle ? options.titleCol : ""
    			},
				simpleData : {
					enable : true
				}
			},
			callback : {
				beforeDrag : function() {
					return false;// 不允许拖拽
				},
				beforeClick : function(treeId, treeNode) {
					var isFunction = typeof options.beforeClick === "function";
					if (isFunction) {
						// 用户自定义事件
						return options.beforeClick(treeId, treeNode);
					}
					// 默认事件
					if (options.onlyLeaf === undefined || options.onlyLeaf) {
						return treeNode && ((!options.trueParent && !treeNode.isParent)
								|| (options.trueParent && !treeNode.trueParent));
					}
					return true;
				},
				onClick : function(e, treeId, treeNode) {
					var index,isFunction = typeof options.onClick === "function";
					if (options.clickMask) {
						index = layer.load({time: 10*1000});
					}
					if (isFunction) {
						// 用户自定义事件
						options.onClick(treeId, treeNode);
					}
					if (options.clickMask) {
						layer.close(index);
					}
				},
				beforeCheck : function(treeId, treeNode) {
					/*console.log("beforeCheck",treeNode)*/
					var isFunction = typeof options.beforeClick === "function";
					if (isFunction) {
						// 用户自定义事件
						return options.beforeClick(treeId, treeNode);
					}
					// 默认事件
					if (options.onlyLeaf === undefined || options.onlyLeaf) {
						if (treeNode && ((!options.trueParent && treeNode.isParent)
								|| (options.trueParent && treeNode.trueParent))) {
							// 重置checked状态
							treeNode.checked = treeNode.getCheckStatus().half;
						}
					}
					return true;
				},
				onCheck : function(e, treeId, treeNode) {
					var index,isFunction = typeof options.onCheck === "function";
					if (options.clickMask) {
						index = layer.load({time: 10*1000});
					}
					if (isFunction) {
						// 用户自定义事件
						options.onCheck(treeId, treeNode);
					}
					if (options.clickMask) {
						layer.close(index);
					}
				}
			}
		};
    	return $.fn.zTree.init($("#" + treeId), ztreeSetting, zNodes);
    }
    
    /**
     * zTree插件:根据数据勾选对应的节点
     */
    that.zTreeChose = function(treeId, options){
    	if (!treeId) {
			return;
		}
    	/*************************配置项:开始***********************/
    	options = $.extend({},{		// 以下为默认值
    		zId: 'id',			// 用于查询zTree中的节点字段,暂时支持一个字段的匹配查询,多字段需要考虑字段的对应关系,多字段请自定定义匹配函数filter
    		dId: 'id',			// 用于从数据源中查找匹配节点对应的字段名,暂时支持一个字段的匹配查询
    		data: [],			// 数据源JSONArray
    		muti: false,		// 是否多选：多选true,单选false
    		event: true,		// 是否触发选择事件:触发true,不触发false
    		chose: true,		// 否勾选：选中true,不选中false
    		isExpandNode: true,	// 选中后是否展开节点:展开true,不展开false
    		onlyLeaf: true,		// 勾选是否和父级节点联动,setting.check.enable=true时有效
    		filter: function(treeId, zId, data, dId){// 匹配方法,
    			return ComUtil.zTreeSearchNodes(treeId,function(node) {
    	   			return (node[zId] == data[dId]);
    	   		}, false);
    		}
    	}, options);
    	/*************************配置项:结束***********************/
    	var zId = options.zId,
    		dId = options.dId,
    		data = options.data,
    		filter = options.filter,
    		isExpandNode = options.isExpandNode;
    	if (data) {
    		var	index = layer.load({time: 10*1000}),timeout;
    		if (timeout) {
    			clearTimeout(timeout);
    		}
    		timeout = setTimeout(function() {
    			for (var i = 0,l = data.length; i < l; i++) {
    				var nodes = filter(treeId, zId, data[i], dId),
    					isArr = ComUtil.isArray(nodes);
    				if (!nodes) {
    					continue;
    				}
					var nodeList = isArr ? nodes : [nodes];
					// TODO 
					ComUtil.zTreeChoseNodes(treeId, nodeList, options);
        			if (!options.muti && nodeList && nodeList.length > 0) {
        				return false;
        			}
    			}
    			clearTimeout(timeout);
				timeout = setTimeout(function() {
					layer.close(index);
				});
    		},100);
    	}
    }
    
    /**
     * zTree插件:根据树节点nodeList勾选节点,此方法不要改成默认加载选择第一个节点,因为其他方法在调用
     * @param treeId
     * 		树ID
     * @param nodeList
     * 		节点数组:[{},{}...]
     * @param options.muti
     * 		是否多选：多选true,单选false
     * @param options.chose
     * 		是否勾选：选中true,不选中false
     * @param options.isExpandNode
     * 		选中后是否展开节点:展开true,不展开false
     */
    that.zTreeChoseNodes = function(treeId, nodeList, options) {
    	if (!treeId || !nodeList) {
			return;
		}
		/*************************配置项:开始***********************/
		options = $.extend({},{		// 以下为默认值
			chose: true,			// 否勾选：选中true,取消选中false
    		muti: false,			// 是否多选：多选true,单选false
    		event: false,			// 是否触发选择事件:触发true,不触发false
    		isExpandNode: false,	// 选中后是否展开节点:展开true,不展开false
    		onlyLeaf: true			// 勾选是否和父级节点联动,setting.check.enable=true时有效
    	}, options);
		/*************************配置项:结束***********************/
		var zTree = $.fn.zTree.getZTreeObj(treeId);
		for (var n = 0,l = nodeList.length; n < l; n++) {
			if (options.muti) {
				var parentNonde = nodeList[n].getParentNode();
				while (options.isExpandNode && parentNonde && !parentNonde.open) {
					zTree.expandNode(parentNonde, true, false);
					parentNonde = parentNonde.getParentNode();
				}
				zTree.checkNode(nodeList[n], options.chose, options.onlyLeaf, options.event);
			} else {
				if (options.chose) {
					zTree.selectNode(nodeList[n]);
				} else {
					zTree.cancelSelectedNode(nodeList[n]);
				}
				if (options.event) {
					zTree.setting.callback.onClick(null, zTree.setting.treeId, nodeList[n]);
				}
			}
		}
    }
    
    
    /**
     * zTree插件:根据数据查询节点并返回
     * @param treeId
     * 		zTree树ID
     * @param filter
     * 		自定义查找方法
     * @param oneOrMore
     * 		查找一个还是多个:false(默认值)/true=单个/多个
     * @return
     * 		单个返回节点json{},多个返回节点数组[{},{}]
     */
    that.zTreeSearchNodes = function(treeId, filter, oneOrMore) {
    	if (typeof filter !== "function")
			return null;
    	oneOrMore = oneOrMore === false ? false : true;
		return $.fn.zTree.getZTreeObj(treeId).getNodesByFilter(filter, oneOrMore); 
    }
    
    /**
     * TODO:以POST的方式打开页面,
     * @bug
     * 目前这个方法还有个BUG就是打开的页面在谷歌或者火狐上刷新会提示“确定提交表单”
     * @param URL
     * 页面地址
     * @param PARAMS
     * 传递的页面参数,JSON格式
     * @param OPENMODE
     * 是否新窗口打开:true/false
     */
    that.postOpenNewWin = function (URL, PARAMS, OPENMODE) {
		var temp_form = document.createElement("form");
		temp_form.id = 'pfrom-'+ new Date().getTime();
		temp_form.action = URL;
		if (OPENMODE) {
			temp_form.target = "_blank";
		}
		temp_form.method = "post";
		temp_form.style.display = "none";
		if (PARAMS) {
			for ( var x in PARAMS) {
				var opt = document.createElement("textarea");
				opt.name = x;
				opt.value = PARAMS[x];
				temp_form.appendChild(opt);
			}
		}
//		temp_form.onsubmit='return false';
		document.body.appendChild(temp_form);
		temp_form.submit();
		document.body.removeChild(temp_form);
	}
    
    /**
	 * 加载智能提示选择控件,见jquery.autocomplete.js下插件使用提示
	 * 
	 * @tips 需要引入jquery.autocomplete相关资源
	 * @param objId
	 * 受益对象
	 * @param URL_
	 * 远程服务地址
	 * @param options
	 * 配置项,具体参考jquery.autocomplete.js
	 */
	that.autoChosen = function (objId, URL_, options) {
		return AutoComp.autocomplete(objId, URL_, options);
	}
	
    /**
     * chosen下拉选择
     * @param obj
     * 要实现chosen的对象标识,形如 #elementId, .elementClazz
     * @param options
     * 配置项
     */
    that.chosen = function (obj, options){
    	var eObj = $(obj);
    	if (!eObj) {
    		return;
    	}
    	/*************************配置项:开始***********************/
    	// TODO chosen的使用方法见API：https://harvesthq.github.io/chosen/options.html
    	options = $.extend({},{
    		debug: false,									// 是否调试
			width: '100%',									// 宽度		
			rtl: false,										// right-to-left
			no_results_text : '天呐,没有找到->',				// 没有匹配项时的提示文字
    	 	allow_single_deselect: true,					// ???
    	 	disable_search: false,							// 是否隐藏搜索框[仅对单选有效]
    	 	enable_split_word_search: false,				// 搜索框仅搜索文本请设置成false
			disable_search_threshold: 10,					// 超过多少个时显示搜索框,默认10个
//			max_selected_options: 5,						// 最多选择多少个项,到达限制会触发chosen:maxselected函数[仅对多选有效]
			placeholder_text_single: '请选择一项...',			// 单选placeholder
			placeholder_text_multiple: '请选择一些...',			// 多选placeholder
			search_contains: true,							// 搜索配置原则是以what[false]开始还是包含waht[true]
			group_search: true,								// ???
			case_sensitive_search: true,					// 是否区分大小写
			display_disabled_options: true,					// 是否显示disabled的项
			display_selected_options: true,					// 是否显示已被选择的项[仅对多选有效]
			include_group_label_in_selected: false,			// 默认情况下,选择仅显示选定选项的文本.将此选项设置为true将显示所选选项的文本和组（如果有）
			hide_results_on_select: true,					// 默认情况下,Chosen的结果在选择选项后隐藏.设置此选项false将在选择后保持结果打开[仅对多选有效]
			cfgMuti: false,									// 配置项是否多选,默认单选false
			cfgGroup: false,								// 配置项是否分组展示,最多展示二级目录,多余3级建议不用chosen插件,请使用树插件
			cfgAppend: false,								// 配置项是追加[true]还是先清空在追加[false]
			cfgAppendBlack: false,							// 配置项是否添加空的选项,默认不添加false
			cfgUrlOrData:'',								// 配置项的数据源地址或者数据对象数组[{},{}]
			cfgParams: null,								// 配置项的数据源地址请求时的参数
			cfgId: 'nodeId',								// 配置项option的value字段
			cfgName: 'nodeName',							// 配置项option的name字段
			cfgShowTile: false,								// 配置项option的title属性是否显示值
			cfgTile: 'nodeName',							// 配置项option的title属性字段
			cfgSelectedArr: null,							// 配置项中需要初始化选中的option的value数组
			cfgFnDisable: null,								// 配置项中需要禁止的选项的匹配规则,参数配置项JSON数据,返回true/false
			cfgFnCallBack: null								// 配置项加载完成以后的回调函数,参数obj,和所有的option数据JsonArr
    	}, options);
    	/*************************配置项:结束***********************/
    	// TODO 绘制配置项
    	var isUrl = typeof (options.cfgUrlOrData) === "string", 
    		datas = options.cfgUrlOrData;
    	// 获取数据
    	if (isUrl) {
    		this.AjaxData.call(ComUtil, obj, options.cfgUrlOrData, function(obj, data){
    			datas = data.data;
    		}, $.extend({},options.cfgParams));
    	}
    	if (options.debug) {
    		console.log(options);
    		console.log(datas);
    		return;
    	}
    	// 解析数据
    	if (datas) {
    		if (!options.cfgAppend) {
    			eObj.html('');
    		}
    		if(options.cfgAppendBlack)
				eObj.append('<option value=""></option>');
    		
    		// 配置多选属性,貌似不起作用
        	if (options.cfgMuti) {
        		eObj.attr('multiple',true);
        		eObj.addClass('tag-input-style');
        	} else {
        		eObj.removeAttr('multiple');
            	eObj.removeClass('tag-input-style')
        	}
        	
    		_append(datas, eObj);
    		
    		/**
    		 * 添加Option
    		 */
    		function _append(arrs, p, level) {
    			for (var i = 0,l = arrs.length; i<l; i++ ) {
        			var row = arrs[i], children = row.children, 
        			val = row[options.cfgId], name = row[options.cfgName],
        			title =  (options.cfgShowTile ? ' title="' + (row[options.cfgTile] ? row[options.cfgTile] : '') + '"' : '' ),
        			groupByAndHasChildren = options.cfgGroup && children && ComUtil.isArray(children) && children.length > 0;
        			if (groupByAndHasChildren) {
        				var labelId = val + '_label' + new Date().getTime();
        				p.append('<optgroup id="'+ labelId + '" label="'+ name +'" ' + title + '></optgroup>');
        				_append(children, $('#' + labelId));
        			} else {
        				var optionId = val + '_option' + new Date().getTime();
        				p.append('<option id="'+ optionId + '" value="'+ val +'" ' + title + ' ' + (_disable(row) ? ' disabled ' : '') + '>' + name +'</option>');
        				$('#optionId').data('data', row);
        			}
        		}
    			
    			/**
    			 * 是否禁止选择
    			 */
    			function _disable(option) {
    				if (typeof options.cfgFnDisable === 'function') {
    					return ComUtil.bool(options.cfgFnDisable(option));
    				}
    				return false;
    			}
    		}
    	}
    	
    	// TODO 披上天使的嫁衣
//    	eObj.chosen('destroy');
    	eObj.trigger("chosen:updated");
    	eObj.chosen(options);
    	
    	// TODO 初始化完成以后的处理
    	if (options.cfgSelectedArr) {
    		ComUtil.chosenUpdate(obj,options.cfgSelectedArr);
    	}
    	
    	if (options.cfgFnCallBack && typeof options.cfgFnCallBack === 'function') {
    		options.cfgFnCallBack(obj, datas);
    	}
    	
    	/*************************配置项:事件描述,开始***********************/
    	// TODO change,chosen:ready,chosen:maxselected,chosen:showing_dropdown,chosen:hiding_dropdown,chosen:no_results
    	/*$(obj).on('change',function(evt, params) {
    		console.log(evt, params);
//    		console.log($(obj).children('option:selected').val(), $(obj).children('option:selected').text());
    		console.log(ComUtil.chosenVals(obj));
    	});*/
    	// TODO chosen:updated,chosen:activate,chosen:open,chosen:close
    	/*$(obj).trigger('chosen:updated');*/
    	/*************************配置项:事件描述,结束***********************/
    }
    
    /**
     * 更新chosen已选中某些值
     * @param obj
     * 要实现chosen的对象标识,形如 #elementId, .elementClazz
     * @param valArr
     * [1,2,3]
     * @return 
     * {value:[...],text:[...]}
     */
    that.chosenVals = function(obj) {
    	var result = {}, value = new Array(), text = new Array();
    	$(obj).children('option:selected').each(function(i,o){
    		var v = $(o).attr('value'), t = $(o).text();
    		if (v) {
    			value.push(v);
        		text.push(t);
    		}
    	});
		return {
			value : value,
			text : text
		}
    }
    
    /**
     * 更新chosen已选中某些值
     * @param obj
     * 要实现chosen的对象标识,形如 #elementId, .elementClazz
     * @param valArr
     * [1,2,3]
     * @param selected
     * 是否选中true/false,默认true
     */
    that.chosenUpdate = function(obj, valArr, selected) {
    	if (valArr) {
    		ComUtil.chosenUnSelectAll(obj);
    		selected = selected === false ? false : true;
    		for (var i = 0,l = valArr.length; i < l; i++) {
    			if (selected) {
    				$(obj + " option[value='" + valArr[i] + "']").attr('selected', selected);
    			} else {
    				$(obj + " option[value='" + valArr[i] + "']").removeAttr('selected');
    			}
			}
        	$(obj).trigger("chosen:updated");
    	}
    }
    
    /**
     * 清空chosen已选值
     * @param obj
     * 要实现chosen的对象标识,形如 #elementId, .elementClazz
     */
    that.chosenUnSelectAll = function(obj){
    	$(obj).val("");
    	$(obj).trigger("chosen:updated");
    }
    
    /**
	 * 加载选择人员的双控件[智能提示控件+按钮选择弹出层控件]
	 * @param objId
	 * @param options
	 */
	that.sysPerson = function(objId, options) {
		// TODO 智能选择
		options = $.extend({
			cfgName : "userfullname",	// 必填显示字段
			cfgId : "userid",	 		// 可配置需要隐藏设置的字段值,不设置此值则不保存隐藏字段
			cfgShowRg : true,    		// 是否显示在右边的字段,默认false
		}, options);
		options.extraParams = $.extend({},{
			isLock: "Y"					// 是否仅选择非锁定人员,为空默认是[Y],否[N]
		}, options.extraParams);
		options = ComUtil.autoChosen(objId, servicerUrl + "syscom/UserCommonAction/commonSearchUser.do", options);
		// TODO 弹出层选择
		$(objId).nextAll("span.input-group-btn").off("click").on("click", function() {
			// 父子页面交互配置项
			var childOptions = $.extend({},{
				chdUrlOrData: servicerUrl + "syscom/UserCommonAction/commonOrgsUsers.do",	// 子页面树加载地址,请尽量使用URL
				chdParams: (function() {												// 子页面树加载参数（需要自定义）
					return $.extend({},{
						mutiType: (options.multiple ? "Y" : "N"),
						isLock: "Y"														// 是否仅选择非锁定人员,为空默认是[Y],否[N]
					}, options.extraParams);											
				})(),
				onlyLeaf: true, 														// 是否仅选择叶子节点,默认[false]
				trueParent: true, 													    // 树节点中是否含trueParent字段
				checkedParentWhenNoLeaf: false,											// 是否在多选时当前节点没有子节点可选时也选中当前节点,默认[false]
				mutiable: options.multiple,												// 子页面树加载后是否多选
				multipleSeparator: options.multipleSeparator,							// 多选时值的分隔符号
				showNodeICon: true,						   								// 是否显示节点图标
				helpSearch: true, 														// 是否显示辅助搜索框,默认不显示[false]
				helpSearchShowRg: true,													// 是否显示辅助搜索框搜索右边展示value,默认不显示[false]
				leftIconClazz: "icon-home", 											// 左侧目录树图标,默认不显示[icon-th-list]
				rightIconClazz: "icon-user", 											// 右侧目录树图标,默认不显示[icon-check]
				rightListShow: true,													// 显示右侧已选栏
				dataColumnId: "userId",													// 选择后返回给父页面隐藏的字段,默认[id]
				dataColumnName: "orgsimpletname",										// 选择后返回给父页面显示的字段,同时也是显示在右边已选框中的字段,默认[name]
				dataColumns:["id"],														// 选择后返回给父页面的额外字段,默认返回dataColumnId,dataColumnName
				chdChiooseObjId: objId,													// 父页面中的选择受益对象,用于子页面获取已选值的显示名称
				chdChiooseHideObjId: (options.cfgHideobj ? options.cfgHideobj : ""),	// 父页面中的选择受益异常对象,默认受益对象后面的隐藏对象元素,用于子页面获取已选值的隐藏ID值
				chdParentCallMethd: null												// 父页面中让子页面确定按钮的回调方法，仅在不使用layer UI默认的弹窗按钮时（即使用子页面自定义的按钮时的回调方法）
			}),
			// 弹出层配置项
			layerOptions = {
				title: "选择人员"								// 窗口名称
			};
			that.plusTreeChoose(objId, childOptions, layerOptions);
		});
	}
    
    /************************/
    /**FRM_SYS_CONFIG的封装***/
    /************************/
    /**
     * 公用配置表配置项组装成chose插件
     * @param obj
     * 受益对象,型如#elementId,.elementClass,建议使用ID
     * @param configCode
     * FRM_SYS_CONFIG表配置项CODE
     * @param options
     * 公用chosen配置
     */
    that.sysChosen = function(obj, configCode, options){
    	configCode = configCode || '';
    	options = $.extend({}, {
    		cfgSub: false,					   // 配置项是CONFIG_CODE对应的子项[true]还是CONFIG_CODE对应项[默认false]
    		cfgMuti: false,					   // 配置项是否多选,默认单选false
			cfgGroup: false,				   // 配置项是否分组展示,最多展示二级目录,多余3级建议不用chosen插件,请使用树插件
    		cfgParams: {
    			configCode: configCode
    		},
			cfgId: 'configValue',				// 配置项option的value字段
			cfgName: 'configName',				// 配置项option的name字段
			cfgTile: 'configName'				// 配置项option的title属性字段
    	}, options);
    	if (options.cfgGroup) {
    		options = $.extend({
    			cfgUrlOrData : servicerUrl + "syscom/SystemConfigAction/getConfigsTree.do",
    		}, options);
    	} else {
    		if (options.cfgSub) {
    			options = $.extend({
        			cfgUrlOrData : servicerUrl + "syscom/SystemConfigAction/getSubConfigs.do",
        		}, options);
    		} else {
    			options = $.extend({
        			cfgUrlOrData : servicerUrl + "syscom/SystemConfigAction/getConfigs.do",
        		}, options);
    		}
    	}
    	// 调用公用chosen插件方法
    	this.chosen.call(that, obj, options);
    }
    
    /**
     * 公用配置表配置项组装成弹出层树形选择插件
     * @param obj
     * 受益对象,型如#elementId,.elementClass,建议使用ID
     * @param configCode
     * FRM_SYS_CONFIG表配置项CODE
     * @param options.childOptions
     * 公用弹出层树形插件配置
     * @param options.layerOptions
     * 公用弹出层配置
     * @return
	 * 返回值会自动根据$(objId)自动设置,如果需要设置隐藏值dataSetIdable=true,则隐藏值会自动设置到$(objId)后面紧接着的隐藏input里
     */
    that.sysPopupTree = function(objId, configCode, options) {
    	var eObj = $(objId);
    	if(!eObj) return;
    	eObj.off("click").on("click", function() {
    		configCode = configCode || '';
        	
        	// 总体配置项
        	options = $.extend({},{
        		debug : false, 						// 是否调试,默认否[false]
        		childOptions: {},
        		layerOptions: {}
        	}, options),
        	
        	// 父子页面交互配置项
    		childOptions = $.extend({},{
    			chdUrlOrData: servicerUrl + "syscom/SystemConfigAction/getConfigsZTree.do",	// 子页面树加载地址,请尽量使用URL
    			chdParams: {
    				configCode: configCode
    			},
    			debug: options.debug, 				// 是否调试,默认否[false]
    			mutiable: false,					// 子页面树加载后是否多选
    			onlyLeaf : true, 					// 是否仅选择叶子节点,默认[false]
    			helpSearch : true, 					// 是否显示辅助搜索框,默认不显示[false]
    			showNodeICon: true, 				// 是否显示节点图标,默认不显示[false]
//    			idKey: 'configId',					// Ztree节点idKey,默认[id]
//				pIdKey: 'parentId',					// Ztree节点pIdKey,默认[pId]
    			expandAll: false,					// Ztree节点是否展开所有,数据太多时展开耗性能
    			chdChiooseObjId: objId				// 父页面中的选择受益对象,用于子页面获取已选值的显示名称
    		}, options.childOptions),
    		
    		// 弹出层配置项
    		layerOptions = $.extend({},{
    			title: "选择配置项"						// 窗口名称
    		}, options.layerOptions);
        	
        	that.plusTreeChoose(objId, childOptions, layerOptions);
    	});
    }
    
    /**
     * 公用配置表配置项组装成弹出层树形下拉选择插件
     * @param obj
     * 受益对象,型如#elementId,.elementClass,建议使用ID
     * @param configCode
     * FRM_SYS_CONFIG表配置项CODE
     * @param options
     * 公用树形下拉树形插件配置
     */
    that.sysChosenTree = function(obj, configCode, option) {
    	configCode = configCode || '';
    	// TODO 后期开发
    }
}